<?php
/**
 * Created by PhpStorm.
 * User: Vito
 * Date: 2022/3/30
 * Time: 16:54
 */

namespace app\command;


use app\common\Enum;
use think\console\command\Make;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
use think\helper\Str;

/**
 * 生成CURD类
 * php think make:curd admin@user/User
 * --only read,save  只允许生成read和save
 * --except read 排除read
 * Class MakeCurd
 * @package app\command
 */
class MakeCurd extends Make
{
    protected $curds = Enum::CURD;

    protected $allow = [];

    protected $currentCurd;

    protected $basic = 'common';

    protected function configure()
    {
        parent::configure(); // TODO: Change the autogenerated stub
        $this->setName('make:curd')
            ->addOption('only', null, Option::VALUE_OPTIONAL, '只生成的CURD')
            ->addOption('except', null, Option::VALUE_OPTIONAL, '排除的CURD')
            ->addOption('basic', null, Option::VALUE_OPTIONAL, 'CURD基类');
    }

    protected function execute(Input $input, Output $output)
    {
        $this->setAllowCurds();

        if ($input->getOption('basic')) {
            $this->basic = $input->getOption('basic');
        }

        foreach ($this->allow as $name) {

            $this->currentCurd = $name;
            $this->type        = 'curd ' . $name;

            parent::execute($input, $output);
        }

        $output->writeln('生成CURD类完成');
    }

    protected function buildClass(string $name)
    {
        $data = parent::buildClass($name);

        return str_replace(['{%basic%}'], [$this->basic], $data);
    }

    protected function getClassName(string $name): string
    {

        $app = '';

        if (strpos($name, '@') !== false) {
            [$app, $name] = explode('@', $name);
        }

        // 没有设置目录则将目录设置为自身的名字
        if (strpos($name, '/') === false) {
            $name = Str::snake($name) . '/' . $name;
        }

        $className = ($app ? $app . '@' : '') . $name;

        return parent::getClassName($className) . ucfirst($this->currentCurd); // TODO: Change the autogenerated stub
    }

    protected function getNamespace(string $app): string
    {
        return 'app' . ($app ? '\\' . $app : '') . '\curd';
    }

    /**
     * 获取需要生成的文件
     * @return string
     */
    protected function getStub()
    {
        return __DIR__ . DIRECTORY_SEPARATOR . 'stubs/curd_' . $this->currentCurd . '.stub';
    }

    /**
     * 设置要生成的CURD类
     * @return $this
     */
    protected function setAllowCurds()
    {
        $allow = $this->curds;

        $only   = $this->input->getOption('only');
        $except = $this->input->getOption('except');

        if ($only) {
            $allow = array_intersect($this->curds, explode(',', $only));
        } elseif ($except) {
            $allow = array_diff($this->curds, explode(',', $except));
        }

        $this->allow = $allow;

        return $this;
    }
}